home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Resources / Developers / XAMPP 1.5.4 / Windows installer / xampp-win32-1.5.4-installer.exe / xampp / php / pear / Auth / PrefManager.php < prev    next >
Encoding:
PHP Script  |  2005-07-07  |  16.0 KB  |  427 lines

  1. <?php
  2. require_once("DB.php");
  3.  
  4. /**
  5.  * A simple preference manager, takes userid, preference name pairs and returns the value
  6.  * of that preference.
  7.  *  
  8.  * CREATE TABLE `preferences` (
  9.  * `user_id` varchar( 255 ) NOT NULL default '',
  10.  * `pref_id` varchar( 32 ) NOT NULL default '',
  11.  * `pref_value` longtext NOT NULL ,
  12.  *     PRIMARY KEY ( `user_id` , `pref_id` )
  13.  * )
  14.  * 
  15.  * @author Jon Wood <jon@jellybob.co.uk>
  16.  * @package Auth_PrefManager
  17.  * @category Authentication
  18.  */
  19. class Auth_PrefManager
  20. {
  21.     /**
  22.      * The database object.
  23.      * @var object
  24.      * @access private
  25.      */
  26.     var $_db;
  27.  
  28.     /**
  29.      * The user name to get preferences from if the user specified doesn't
  30.      * have that preference set.
  31.      * @var string
  32.      * @access private
  33.      */
  34.     var $_defaultUser = "__default__";
  35.  
  36.     /**
  37.      * Should we search for default values, or just fail when we find out that
  38.      * the specified user didn't have it set.
  39.      * 
  40.      * @var bool
  41.      * @access private
  42.      */
  43.     var $_returnDefaults = true;
  44.  
  45.     /**
  46.      * The table containing the preferences.
  47.      * @var string
  48.      * @access private
  49.      */
  50.     var $_table = "preferences";
  51.  
  52.     /**
  53.      * The column containing user ids.
  54.      * @var string
  55.      * @access private
  56.      */
  57.     var $_userColumn = "user_id";
  58.  
  59.     /**
  60.      * The column containing preference names.
  61.      * @var string
  62.      * @access private
  63.      */
  64.     var $_nameColumn = "pref_id";
  65.  
  66.     /**
  67.      * The column containing preference values.
  68.      * @var string
  69.      * @access private
  70.      */
  71.     var $_valueColumn = "pref_value";
  72.  
  73.     /**
  74.      * The quoted value column.
  75.      * @var string
  76.      * @access private
  77.      */
  78.     var $_valueColumnQuoted = "pref_value";
  79.     
  80.     /**
  81.      * The session variable that the cache array is stored in.
  82.      * @var string
  83.      * @access private
  84.      */
  85.      var $_cacheName = "prefCache";
  86.  
  87.     /**
  88.      * The last error given.
  89.      * @var string
  90.      * @access private
  91.      */
  92.     var $_lastError;
  93.  
  94.     /**
  95.      * Defines whether the cache should be used or not.
  96.      * @var bool
  97.      * @access private
  98.      */
  99.     var $_useCache = true;
  100.     
  101.     /**
  102.      * Defines whether values should be serialized before saving.
  103.      * @var bool
  104.      * @access private
  105.      */
  106.     var $_serialize = false;
  107.     
  108.     /**
  109.      * Constructor
  110.      * 
  111.      * Options:
  112.      *  table: The table to get prefs from. [preferences]
  113.      *  userColumn: The field name to search for userid's [user_id]
  114.      *  nameColumn: The field name to search for preference names [pref_name]
  115.      *  valueColumn: The field name to search for preference values [pref_value]
  116.      *  defaultUser: The userid assigned to default values [__default__]
  117.      *  cacheName: The name of cache in the session variable ($_SESSION[cacheName]) [prefsCache]
  118.      *  useCache: Whether or not values should be cached.
  119.      *  serialize: Should preference values be serialzed before saving?
  120.      *
  121.      * @param string $dsn The DSN of the database connection to make, or a DB object.
  122.      * @param array $properties An array of properties to set.
  123.      * @param string $defaultUser The default user to manage for.
  124.      * @return bool Success or failure.
  125.      * @access public
  126.      */
  127.     function Auth_PrefManager($dsn, $properties = NULL)
  128.     {
  129.         // Connect to the database.
  130.         if (isset($dsn)) {
  131.             if (is_string($dsn)) {
  132.                 $this->_db = DB::Connect($dsn);
  133.                 if (DB::isError($this->_db)) {
  134.                     $this->_lastError = "DB Error: ".$this->_db->getMessage();
  135.                 }
  136.             } else if (is_subclass_of($dsn, 'db_common')) {
  137.                 $this->_db = &$dsn;
  138.             } else {
  139.                 $this->_lastError = "Invalid DSN specified.";
  140.                 return false;
  141.             }
  142.         } else {
  143.             $this->_lastError = "No DSN specified.";
  144.             return false;
  145.         }
  146.  
  147.         if (is_array($properties)) {
  148.             if (isset($properties["table"]))        { $this->_table = $this->_db->quoteIdentifier($properties["table"]); }
  149.             if (isset($properties["userColumn"]))   { $this->_userColumn = $this->_db->quoteIdentifier($properties["userColumn"]); }
  150.             if (isset($properties["nameColumn"]))   { $this->_nameColumn = $this->_db->quoteIdentifier($properties["nameColumn"]); }
  151.             if (isset($properties["valueColumn"]))  { $this->_valueColumn = $properties["valueColumn"]; }
  152.             if (isset($properties["valueColumn"]))  { $this->_valueColumnQuoted = $this->_db->quoteIdentifier($properties["valueColumn"]); }
  153.             if (isset($properties["defaultUser"]))  { $this->_defaultUser = $properties["defaultUser"]; }
  154.             if (isset($properties["cacheName"]))    { $this->_cacheName = $properties["cacheName"]; }
  155.             if (isset($properties["useCache"]))     { $this->_useCache = $properties["useCache"]; }
  156.             if (isset($properties["serialize"]))    { $this->_serialize = $properties["serialize"]; }
  157.         }
  158.  
  159.         return true;
  160.     }
  161.  
  162.     function setReturnDefaults($returnDefaults = true)
  163.     {
  164.         if (is_bool($returnDefaults)) {
  165.             $this->_returnDefaults = $returnDefaults;
  166.         }
  167.     }
  168.  
  169.     /**
  170.      * Sets whether the cache should be used.
  171.      * 
  172.      * @param bool $use Should the cache be used.
  173.      * @access public
  174.      */
  175.     function useCache($use = true)
  176.     {
  177.         $this->_useCache = $use;
  178.     }
  179.     
  180.     /**
  181.      * Cleans out the cache.
  182.      * 
  183.      * @access public
  184.      */
  185.     function clearCache()
  186.     {
  187.         unset($_SESSION[$this->_cacheName]);
  188.     }
  189.  
  190.     /**
  191.      * Get a preference for the specified user, or, if returning default values
  192.      * is enabled, the default.
  193.      * 
  194.      * @param string $user_id The user to get the preference for.
  195.      * @param string $pref_id The preference to get.
  196.      * @param bool $showDefaults Should default values be searched (overrides the global setting).
  197.      * @return mixed The value if it's found, or NULL if it isn't.
  198.      * @access public
  199.      */
  200.     function getPref($user_id, $pref_id, $showDefaults = true)
  201.     {
  202.         if (isset($_SESSION[$this->_cacheName][$user_id][$pref_id]) && $this->_useCache) {
  203.             // Value is cached for the specified user, so give them the cached copy.
  204.             return $_SESSION[$this->_cacheName][$user_id][$pref_id];
  205.         } else {
  206.             // Not cached, search the database for this user's preference.
  207.             $query = sprintf("SELECT * FROM %s WHERE %s=%s AND %s=%s", $this->_table,
  208.                                                                    $this->_userColumn,
  209.                                                                        $this->_db->quote($user_id),
  210.                                                                        $this->_nameColumn,
  211.                                                                        $this->_db->quote($pref_id));
  212.             $result = $this->_db->query($query);
  213.             if (DB::isError($result)) {
  214.                 // Ouch! The query failed!
  215.                 $this->_lastError = "DB Error: ".$result->getMessage();
  216.                 return NULL;
  217.             } else if ($result->numRows()) {
  218.                 // The query found a value, so we can cache that, and then return it.
  219.                 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
  220.                 $_SESSION[$this->_cacheName][$user_id][$pref_id] = $this->_unpack($row[$this->_valueColumn]);
  221.                 return $_SESSION[$this->_cacheName][$user_id][$pref_id];
  222.             } else if ($this->_returnDefaults && $showDefaults) {
  223.                 // I was doing this with a call to getPref again, but it threw things into an
  224.                 // infinite loop if the default value didn't exist. If you can fix that, it would
  225.                 // be great ;)
  226.                 if (isset($_SESSION[$this->_cacheName][$this->_defaultUser][$pref_id]) && $this->_useCache) {
  227.                     $_SESSION[$this->_cacheName][$user_id][$pref_id] = $_SESSION[$this->_cacheName][$this->_defaultUser][$pref_id];
  228.                     return $_SESSION[$this->_cacheName][$this->_defaultUser][$pref_id];
  229.                 } else {
  230.                     $query = sprintf("SELECT * FROM %s WHERE %s=%s AND %s=%s", $this->_table,
  231.                                                                                $this->_userColumn,
  232.                                                                                $this->_db->quote($this->_defaultUser),
  233.                                                                                $this->_nameColumn,
  234.                                                                                $this->_db->quote($pref_id));
  235.                     $result = $this->_db->query($query);
  236.                     if (DB::isError($result)) {
  237.                         $this->_lastError = "DB Error: ".$result->getMessage();
  238.                         return NULL;
  239.                     } else {
  240.                         if ($result->numRows()) {
  241.                             $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
  242.                             $_SESSION[$this->_cacheName][$this->_defaultUser][$pref_id] = $this->_unpack($row[$this->_valueColumn]);
  243.                             $_SESSION[$this->_cacheName][$user_id][$pref_id] = $_SESSION[$this->_cacheName][$this->_defaultUser][$pref_id];
  244.                             return $_SESSION[$this->_cacheName][$user_id][$pref_id];
  245.                         } else {
  246.                             return NULL;
  247.                         }
  248.                     }
  249.                 }
  250.             } else {
  251.                 // We've used up all the resources we're allowed to search, so return a NULL.
  252.                 return NULL;
  253.             }
  254.         }
  255.     }
  256.  
  257.     /**
  258.     * A shortcut function for getPref($this->_defaultUser, $pref_id, $value),
  259.     * useful if you have a logged in user, but want to get defaults anyway.
  260.     *
  261.     * @param string $pref_id The name of the preference to get.
  262.     * @return mixed The value if it's found, or NULL if it isn't.
  263.     * @access public
  264.     */
  265.     function getDefaultPref($pref_id)
  266.     {
  267.         return $this->getPref($this->_defaultUser, $pref_id);
  268.     }
  269.  
  270.     /**
  271.      * Set a preference for the specified user.
  272.      * 
  273.      * @param string $user_id The user to set for.
  274.      * @param string $pref_id The preference to set.
  275.      * @param mixed $value The value it should be set to.
  276.      * @return bool Sucess or failure.
  277.      * @access public
  278.      */
  279.     function setPref($user_id, $pref_id, $value)
  280.     {
  281.         // Start off by checking if the preference is already set (if it is we need to do
  282.         // an UPDATE, if not, it's an INSERT.
  283.         if ($this->_exists($user_id, $pref_id, false)) {
  284.             $query = sprintf("UPDATE %s SET %s=%s WHERE %s=%s AND %s=%s", $this->_table,
  285.                                                                           $this->_valueColumnQuoted,
  286.                                                                           $this->_db->quote($this->_pack($value)),
  287.                                                                           $this->_userColumn,
  288.                                                                           $this->_db->quote($user_id),
  289.                                                                           $this->_nameColumn,
  290.                                                                           $this->_db->quote($pref_id));
  291.         } else {
  292.             $query = sprintf("INSERT INTO %s (%s, %s, %s) VALUES(%s, %s, %s)", $this->_table,
  293.                                                                                $this->_userColumn,
  294.                                                                                $this->_nameColumn,
  295.                                                                                $this->_valueColumnQuoted,
  296.                                                                                $this->_db->quote($user_id),
  297.                                                                                $this->_db->quote($pref_id),
  298.                                                                                $this->_db->quote($this->_pack($value)));
  299.         }
  300.         $result = $this->_db->query($query);
  301.         if (DB::isError($result)) {
  302.             $this->_lastError = "DB Error: ".$result->getMessage();
  303.             return false;
  304.         } else {
  305.         if ($this->_useCache) {
  306.             $_SESSION[$this->_cacheName][$user_id][$pref_id] = $value;
  307.         }
  308.             return true;
  309.         }
  310.     }
  311.  
  312.     /**
  313.     * A shortcut function for setPref($this->_defaultUser, $pref_id, $value)
  314.     *
  315.     * @param string $pref_id The name of the preference to set.
  316.     * @param mixed $value The value to set it to.
  317.     * @return bool Sucess or failure.
  318.     * @access public
  319.     */
  320.     function setDefaultPref($pref_id, $value)
  321.     {
  322.         return $this->setPref($this->_defaultUser, $pref_id, $value);
  323.     }
  324.  
  325.     /**
  326.     * Deletes a preference for the specified user.
  327.     * 
  328.     * @param string $user_id The userid of the user to delete from.
  329.     * @param string $pref_id The preference to delete.
  330.     * @return bool Success/Failure
  331.     * @access public
  332.     */
  333.     function deletePref($user_id, $pref_id)
  334.     {
  335.         if ($this->getPref($user_id, $pref_id) == NULL) {
  336.             // The user doesn't have this variable anyway ;)
  337.             return true;
  338.         } else {
  339.             $query = sprintf("DELETE FROM %s WHERE %s=%s AND %s=%s", $this->_table,
  340.                                                                      $this->_userColumn,
  341.                                                                      $this->_db->quote($user_id),
  342.                                                                      $this->_nameColumn,
  343.                                                                      $this->_db->quote($pref_id));
  344.             $result = $this->_db->query($query);
  345.             if (DB::isError($result)) {
  346.                 $this->_lastError = "DB Error: ".$result->getMessage();
  347.                 return false;
  348.             } else {
  349.                 if ($this->_useCache) {
  350.                     unset($_SESSION[$this->_cacheName][$user_id][$pref_id]);
  351.                 }
  352.                 return true;
  353.             }
  354.         }
  355.     }
  356.  
  357.     /**
  358.     * Deletes a preference for the default user.
  359.     * 
  360.     * @param string $pref_id The preference to delete.
  361.     * @return bool Success/Failure
  362.     * @access public
  363.     */
  364.     function deleteDefaultPref($pref_id)
  365.     {
  366.         return $this->deletePref($this->_defaultUser, $pref_id);
  367.     }
  368.     
  369.     /**
  370.      * Checks if a preference exists in the database.  
  371.      *
  372.      * @param string $user_id The userid of the preference owner.
  373.      * @param string $pref_id The preference to check for.
  374.      * @return bool True if the preference exists.
  375.      * @access private
  376.      */
  377.     function _exists($user_id, $pref_id)
  378.     {
  379.         $query = sprintf("SELECT COUNT(%s) FROM %s WHERE %s=%s AND %s=%s", $this->_nameColumn,
  380.                                                                            $this->_table,
  381.                                                                            $this->_userColumn,
  382.                                                                            $this->_db->quoteSmart($user_id),
  383.                                                                            $this->_nameColumn,
  384.                                                                            $this->_db->quote($pref_id));
  385.         $result = $this->_db->getOne($query);
  386.         if (DB::isError($result)) {
  387.             $this->_lastError = "DB Error: ".$result->getMessage();
  388.             return false;
  389.         } else {
  390.             return (bool)$result;
  391.         }
  392.     }
  393.  
  394.     /**
  395.      * Does anything needed to prepare a value for saving in the database.
  396.      *
  397.      * @param mixed $value The value to be saved.
  398.      * @return string The value in a format valid for saving to the database.
  399.      * @access private
  400.      */
  401.     function _pack($value)
  402.     {
  403.         if ($this->_serialize) {
  404.             return serialize($value);
  405.         } else {
  406.             return $value;
  407.         }
  408.     }
  409.     
  410.     /**
  411.      * Does anything needed to create a value of the preference, such as unserializing.
  412.      *
  413.      * @param string $value The value of the preference.
  414.      * @return mixed The unpacked version of the preference.
  415.      * @access private
  416.      */
  417.     function _unpack($value)
  418.     {
  419.         if ($this->_serialize) {
  420.             return unserialize($value);
  421.         } else {
  422.             return $value;
  423.         }
  424.     }
  425. }
  426. ?>
  427.